昨天我們裝好了 AWS CLI,現在自己的電腦也能透過終端機操作 AWS。
接下來要處理另一個部署時常常遇到的問題:「為何我的電腦明明跑得動,到了你的電腦或是雲端就不行了!?」
今天來認識 Docker,看看它怎麼幫我們減少環境差異,再把 Docker 裝好,替明天的容器實作做好準備!
d(・∀・)b
我們平常把專案 clone 下來,通常會先執行 npm install,再用 npm run dev 啟動。
但同一份程式碼,換一台電腦就一定能跑嗎?不一定喔。
例如:
所以,能不能順利執行,不只取決於「程式碼是不是同一份」,也跟「執行環境準備好了沒」有關。
Docker 可以讓我們把應用程式、需要的執行環境與相依套件,整理成一份 Image(映像檔),再根據它建立 Container(容器)來執行。
(圖片參考來源:https://www.netapp.com/zh-hant/blog/containers-vs-vms/)
這樣就能讓本機測試與伺服器部署使用同一份 Image,減少每次換機器都要重新準備環境所產生的差異。
那剛剛提到的 Image 和 Container 又是什麼?接下來先把這兩個名詞分清楚。
Container 是一個 Linux 上用來執行程式的隔離環境,裡面可以執行一個或多個 Process
在 macOS 上使用 Docker Desktop 時,它會透過 Linux vm 執行這些容器;如果是在 Linux 上直接使用 Docker Engine,就不需要為此另外建立虛擬機。
簡單來說,當程式(Program)執行起來就會變成 Process 。舉個例子:啟動 Node.js 來執行我們的 program 時,就會產生 process
我們可以讓一個 container 執行 Node.js 服務,另一個 container 執行資料庫。它們各自有自己的行程與檔案系統視圖。
它用兩個重要的 Linux 核心機制:
不過,Container 的隔離不代表完全不會互相影響。如果沒有設定適當的資源限制,一個容器大量消耗資源,仍可能影響其他容器。
另外,一般 Linux 容器是在共用核心的情況下隔離行程;VM 則各自執行自己的客體作業系統與核心,兩者的隔離邊界不同。
因此,容器不需要像 VM 一樣,各自啟動一套完整的作業系統,但也不能把它的隔離方式當成和 VM 完全一樣。
不過,容器裡的 Node.js、套件和程式碼,是從哪裡來的?Docker 怎麼知道要準備哪些東西?
這就要接著認識 Image 了。
剛剛提到,容器裡需要有程式、相依套件與執行環境。這些內容可以事先準備成一份 Image,讓 Docker 根據它建立容器。
Image 可以想成建立容器用的「唯讀範本」,裡面包含執行一個應用程式所有需要的東西(文件系統、依賴 Library、環境變數、啟動參數...)
例如,官方的 Node.js Image 已經準備好 Node.js 執行環境。我們可以直接用它建立容器,在容器裡執行 Node.js,不需要先在自己的電腦安裝同一版本的 Node.js。
主要有兩種:
別人做的:
PS. docker commit,把容器裡的檔案變更與設定保存成一份新的 Image,這個操作之後再介紹。

簡單記:
同一份 Image 可以建立多個 Container,每個容器都有自己的執行狀態。
而且,Image 是唯讀的,在容器裡新增或修改檔案,不會直接改動原本的 Image。所以下次再用同一份 Image 建立新容器時,也不會自動帶入上一個容器裡做過的修改。
前往 Docker Desktop 的 macOS 官方安裝頁面,依照自己的 Mac 選擇版本:
開啟下載的 Docker.dmg,把 Docker 圖示拖曳到 Applications(應用程式)資料夾,再從應用程式資料夾開啟 Docker。
第一次啟動時,閱讀使用條款,確認同意後繼續。如果出現設定選項,可以使用建議設定(Use recommended settings),依提示完成設定。
如果要求輸入密碼,這裡使用的是這台 Mac 的登入密碼,與 AWS 帳號無關。
保持 Docker Desktop 開啟,等待引擎啟動完成,再打開終端機執行:
docker version
成功的話會看到兩個區塊:
Cannot connect to the Docker daemon,可能是你的 Docker Desktop 沒有開,開啟後並等待引擎啟動完成後再試一次。PS. docker --version 只會顯示 CLI 的版本;這裡使用 docker version,是為了連後面的 Docker Engine 一起確認。
今天就到這裡,工具也準備好了,明天就來親手啟動第一個容器,看看這些觀念實際操作起來是什麼樣子!
ヽ(✿゚▽゚)ノ
Docker Container 基礎入門篇
營養師不開菜單的第二十八天 - Next.js in Docker,跟上容器化技術
Containers vs. Virtual Machines (VMs): What's the Difference?